﻿using Smile.Imaging;
using Smile.Network.Http;
using Smile.Useful;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Threading.Tasks;
using Windows.Media.Capture;
using Windows.Storage;
using Windows.Storage.Pickers;
using Windows.Storage.Provider;
using Windows.Storage.Streams;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml.Media.Imaging;

namespace Smile.Mvvm.Service
{
    /// <summary>Service which manage operations with media storage.</summary>
    public class MediaStorageService : IMediaStorageService
    {
        // @Properties
        public object CameraCapture
        {
            get 
            {
                return _mediaCapture;
            }
        }

        // @Public
        public async Task<IImage> CameraCaptureAsync()
        {
            await _mediaCapture.InitializeAsync();
            await _mediaCapture.StartPreviewAsync();

            return null;
        }

        public async Task<IImage> PhotoChooseAsync()
        {
            // Verify if application is not snaped.
            if (ApplicationView.Value != ApplicationViewState.Snapped || 
                ApplicationView.TryUnsnap() == true)
            {
                FileOpenPicker openPicker = new FileOpenPicker();
                openPicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.PicturesLibrary;
                openPicker.ViewMode = PickerViewMode.Thumbnail;

                // Filter to include a sample subset of file types.
                openPicker.FileTypeFilter.Clear();
                openPicker.FileTypeFilter.Add(".bmp");
                openPicker.FileTypeFilter.Add(".png");
                openPicker.FileTypeFilter.Add(".jpeg");
                openPicker.FileTypeFilter.Add(".jpg");

                // Open the file picker.
                StorageFile file = await openPicker.PickSingleFileAsync();

                // Verify if user have select an image.
                if (file != null)
                {
                    IRandomAccessStream fileStream = await file.OpenAsync(FileAccessMode.Read);
                    var reader = new DataReader(fileStream.GetInputStreamAt(0));
                    var bytes = new byte[fileStream.Size];
                    await reader.LoadAsync((uint)fileStream.Size);
                    reader.ReadBytes(bytes);

                    return new Image(bytes);
                }
            }
            return null;
        }

        public async Task<bool> SavePictureAsync(string title, byte[] byteArray)
        {
            // Verify if application is not snaped.
            if (ApplicationView.Value != ApplicationViewState.Snapped ||
                ApplicationView.TryUnsnap() == true)
            {
                FileSavePicker savePicker = new FileSavePicker();
                savePicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
                savePicker.FileTypeChoices.Add("Images", new List<string>() 
                { 
                    ".jpg",
                    ".jpeg",
                    ".png"
                });
                savePicker.SuggestedFileName = title;

                StorageFile file = await savePicker.PickSaveFileAsync();
                if (file != null)
                {
                    CachedFileManager.DeferUpdates(file);
                    await FileIO.WriteBytesAsync(file, byteArray);

                    FileUpdateStatus status = await CachedFileManager.CompleteUpdatesAsync(file);
                    if (status == FileUpdateStatus.Complete)
                    {
                        return true;
                    }
                    else
                    {
                        throw new Exception("Cannot save " + title + ".");
                    }
                }
            }
            return false;
        }

        public async Task<bool> SavePictureAsync(string title, string uriString)
        {
            return await SavePictureAsync(title, new Uri(uriString));
        }

        public async Task<bool> SavePictureAsync(string title, Uri uri)
        {
            var request = new HttpDownloader();
            var response = await request.DownloadAsync(uri);

            if (response.Status != HttpStatusCode.OK)
            {
                return false;
            }
            return await SavePictureAsync(title, response.ContentBytes);
        }


        // @Private
        MediaCapture    _mediaCapture = new MediaCapture();
    }
}
